﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using Up2Link.Server;
using Up2Link.SegString;
using Up2Link.Util;

using LastLand.Data;

namespace LastLand.Core
{
    public class CLastLand
    {
        private static CServer<CMessageSS> server = null;
        private static Boolean serverOn = false;

        public static void Main(String[] _args)
        {
            CData.connections = new Dictionary<Int32, CPlayer>();
            CData.playerData = new Dictionary<String, String>();

            InitLoad();

            CConsole console = new CConsole();
            CCommand command = new CCommand(console);

            serverOn = true;
            console.SendOutput("欢迎使用《废土 Last Land (开发名)》服务器程序");
            console.SendOutput("输入help阅读服务器使用说明");
            console.Start();
            while (serverOn)
            {
                String input = console.ReceiveInput();
                if (input != null)
                {
                    Char[] d = { CConst.DELIMITER_COMMAND };
                    String[] split = input.Split(d);
                    if (split.Length >= 2)
                    {
                        command.ExecuteCommand(split[0].ToLowerInvariant().Trim(), split[1].ToLowerInvariant().Trim());
                    }
                    else
                    {
                        command.ExecuteCommand(split[0].ToLowerInvariant().Trim(), null);
                    }
                }
                if (server != null && server.isServerOn())
                {
                    CServerLog log = server.GetServerLog();
                    if (log != null)
                    {
                        Log(console, log);
                    }

                    CMessagePack<CMessageSS> msgPack = server.Receive();
                    if (msgPack != null)
                    {
                        Message(console, msgPack);
                    }
                }
                if (server != null && !server.isServerOn())
                {
                    server = null;
                    console.SendOutput("");
                    console.SendOutput("服务器遇到异常，请重新启动服务器监听");
                }
            }
            console.Close();

            SaveData();

            System.Console.ReadKey(true);
        }

        private static void InitLoad()
        {
            FileStream fs = new FileStream(CConst.USER_LIST_TXT, FileMode.OpenOrCreate, FileAccess.Read);
            StreamReader sr = new StreamReader(fs);

            String line = sr.ReadLine();
            Char[] d = { CConst .DELIMITER_USERNAME_PASSWORD };
            while (line != null)
            {
                String[] userdata = line.Split(d);
                String username = userdata[0];
                String password = userdata[1];
                CData.playerData.Add(username, password);

                line = sr.ReadLine();
            }

            sr.Close();
        }

        private static void SaveData()
        {
            FileStream fs = new FileStream(CConst.USER_LIST_TXT, FileMode.Create, FileAccess.Write);
            StreamWriter sw = new StreamWriter(fs);

            //System.Console .WriteLine("");
            //System.Console.WriteLine("正在保存用户信息");
            foreach (String username in CData.playerData.Keys)
            {
                String password = CData.playerData[username];
                sw.WriteLine(username + CConst.DELIMITER_USERNAME_PASSWORD + password);
                //System.Console.WriteLine(username + "," + password);
            }

            sw.Close();

            //System.Console.WriteLine("用户信息保存完毕");
        }

        private static void Command(CConsole _console, String _command, String _args)
        {
            if (_command.Equals("exit"))
            {
                serverOn = false;
                CloseServer(_console);
            }
            else if (_command.Equals("help"))
            {
                Help(_console);
            }
            else if (_command.Equals("iplist"))
            {
                Iplist(_console);
            }
            else if (_command.Equals("status"))
            {
                Status(_console);
            }
            else if (_command.Equals("talk"))
            {
                Talk(_console, _args);
            }
            else if (_command.Equals("start"))
            {
                if (_args != null)
                {
                    Char[] d = { CConst.DELIMITER_ARGUMENT };
                    String[] args = _args.Split(d);
                    if (args.Length >= 2)
                    {
                        StartServer(_console, args[0].Trim(), Int32.Parse(args[1].Trim()));
                    }
                    else
                    {
                        StartServer(_console, args[0].Trim(), 8802);
                    }
                }
                else
                {
                    _console.SendOutput("");
                    _console.SendOutput("你输入的指令是：" + _command);
                    _console.SendOutput("指令参数过少");
                }
            }
            else if (_command.Equals("close"))
            {
                CloseServer(_console);
            }
            else if (_command.Equals("restart"))
            {
                if (_args != null)
                {
                    Char[] d = { CConst.DELIMITER_ARGUMENT };
                    String[] args = _args.Split(d);
                    if (args.Length >= 2)
                    {
                        RestartServer(_console, args[0].Trim(), Int32.Parse(args[1].Trim()));
                    }
                    else
                    {
                        RestartServer(_console, args[0].Trim(), 8802);
                    }
                }
                else
                {
                    _console.SendOutput("");
                    _console.SendOutput("你输入的指令是：" + _command);
                    _console.SendOutput("指令参数过少");
                }
            }
            else
            {
                _console.SendOutput("");
                _console.SendOutput("你输入的指令是：" + _command);
                _console.SendOutput("无法解析的指令，输入help阅读服务器使用说明");
            }
        }

        private static void Talk(CConsole _console, String _args)
        {
            foreach (Int32 index in CData.connections.Keys)
            {
                CMessageSS closeMsg = new CMessageSS(1, 0, 0, _args);
                CMessagePack<CMessageSS> msgPack = new CMessagePack<CMessageSS>(closeMsg, index);
                server.Send(msgPack);
            }
        }

        private static void Status(CConsole _console)
        {
            _console.SendOutput("");
            if (server != null)
            {
                _console.SendOutput("服务器指针不为空");
                if (server.isServerOn())
                {
                    _console.SendOutput("服务器运作中");
                }
                else
                {
                    _console.SendOutput("服务器已终止");
                }
            }
            else
            {
                _console.SendOutput("服务器指针为空");
            }
        }

        private static void Iplist(CConsole _console)
        {
            _console.SendOutput("");
            CIPProbe ipProbe = new CIPProbe();
            Int32 addressCount = ipProbe.AddressCount;
            if (addressCount > 0)
            {
                _console.SendOutput("这台机器的ip地址列表：");
                for (Int32 i = 0; i < addressCount; i++)
                {
                    _console.SendOutput(i + " ： " + ipProbe.AdrStrings[i]);
                }
            }
            else
            {
                _console.SendOutput("无法找到这台机器的ip地址");
            }
        }

        private static void Help(CConsole _console)
        {
            _console.SendOutput("");
            FileStream fs = new FileStream("help.txt", FileMode.OpenOrCreate);
            StreamReader sr = new StreamReader(fs);

            String line = sr.ReadLine();
            Char[] d = {'@'};
            while (line != null)
            {
                String[] cmdDoc = line.Split(d);
                foreach (String str in cmdDoc)
                {
                    _console.SendOutput(str);
                }                
                line = sr.ReadLine();
            }

            fs.Close();
        }

        private static void StartServer(CConsole _console, String _address, Int32 _port)
        {
            if (server == null)
            {
                server = new CServer<CMessageSS>();
                server.Start(_address, _port);

                _console.SendOutput("");
                _console.SendOutput("服务器启动，开始监听 " + _address + ":" + _port);
            }
            else
            {
                _console.SendOutput("");
                _console.SendOutput("服务器已经启动");
            }
        }

        private static void CloseServer(CConsole _console)
        {
            if (server != null && server.isServerOn())
            {
                CData.connections.Clear();

                server.Close();
                server = null;

                _console.SendOutput("");
                _console.SendOutput("服务器关闭");
            }
            else
            {
                _console.SendOutput("");
                _console.SendOutput("服务器已经关闭");
            }
        }

        private static void RestartServer(CConsole _console, String _address, Int32 _port)
        {
            if (server != null && server.isServerOn())
            {
                CData.connections.Clear();
                server.Close();

                server = new CServer<CMessageSS>();
                server.Start(_address, _port);

                _console.SendOutput("");
                _console.SendOutput("服务器重新启动，开始监听 " + _address + ":" + _port);
            }
            else
            {
                _console.SendOutput("");
                _console.SendOutput("服务器已经关闭");
            }
        }

        private static void Log(CConsole _console, CServerLog _log)
        {
            if (_log.logCode == CServerLog.NEW_CLIENT_CONNECTION)
            {
                CPlayer tempPlayer = new CPlayer();
                CData.connections.Add(_log.logMessage, tempPlayer);

                _console.SendOutput("");
                _console.SendOutput("有一个新的用户连接到服务器");
                _console.SendOutput("服务器为他分配了" + _log.logMessage + "号连接");
            }
            else if (_log.logCode == CServerLog.CLIENT_DISCONNECTED)
            {
                CData.connections.Remove(_log.logMessage);

                _console.SendOutput("");
                _console.SendOutput("有一个用户从服务器掉线了");
                _console.SendOutput("他的连接号是 " + _log.logMessage);
            }
            else if (_log.logCode == CServerLog.SERVER_EXCEPTION)
            {
                _console.SendOutput("");
                _console.SendOutput("厄，我们遇到大麻烦了 ：（");
                _console.SendOutput("服务器出现未知异常");
            }
            else
            {
                _console.SendOutput("");
                _console.SendOutput("厄，我们遇到真正的大麻烦了 ：（");
                _console.SendOutput("服务器生成了不可解析的log消息");
            }
        }

        private static void Message(CConsole _console, CMessagePack<CMessageSS> _msgPack)
        {
            CMessageSS msg = _msgPack.message;
            if (msg.MsgCode == 0)
            {
                server.CloseConnection(_msgPack.index);
                CData.connections.Remove(_msgPack.index);

                _console.SendOutput("");
                _console.SendOutput(_msgPack.index + "号客户端断开连接");
            }
            else if (msg.MsgCode == 1)
            {

            }
            else if (msg.MsgCode == 11)
            {
                if (msg.FinFlag == 1)
                {
                    CData.connections[_msgPack.index].Msg = msg;
                }
                else if (msg.FinFlag == 0)
                {
                    String username = CData.connections[_msgPack.index].Msg.MsgContent;
                    String password = msg.MsgContent;
                    if (CData.connections[_msgPack.index].Status == 0)
                    {
                        if (!CData.playerData.ContainsKey(username))
                        {
                            CData.playerData.Add(username, password);
                            CMessageSS okMsg = new CMessageSS(10, 0, 0, "");
                            CMessagePack<CMessageSS> okMsgPack = new CMessagePack<CMessageSS>(okMsg, _msgPack.index);
                            server.Send(okMsgPack);

                            _console.SendOutput("");
                            _console.SendOutput(_msgPack.index + "号客户端成功创建了一个新用户：" + username);
                        }
                        else
                        {
                            CMessageSS nameExistMsg = new CMessageSS(11, 0, 0, username);
                            CMessagePack<CMessageSS> nameExistMsgPack = new CMessagePack<CMessageSS>(nameExistMsg, _msgPack.index);
                            server.Send(nameExistMsgPack);

                            _console.SendOutput("");
                            _console.SendOutput(_msgPack.index + "号客户端尝试创建新用户，但用户名已经存在：" + username);
                        }
                    }
                    else
                    {
                        CMessageSS clientLoggedInMsg = new CMessageSS(13, 0, 0, username);
                        CMessagePack<CMessageSS> clientLoggedInMsgPack = new CMessagePack<CMessageSS>(clientLoggedInMsg, _msgPack.index);
                        server.Send(clientLoggedInMsgPack);

                        _console.SendOutput("");
                        _console.SendOutput(_msgPack.index + "号客户端尝试创建新用户，但该客户端已经登录游戏：" + username);
                    }
                }
            }
            else if (msg.MsgCode == 12)
            {
                if (msg.FinFlag == 1)
                {
                    CData.connections[_msgPack.index].Msg = msg;
                }
                else if (msg.FinFlag == 0)
                {
                    String username = CData.connections[_msgPack.index].Msg.MsgContent;
                    String password = msg.MsgContent;
                    if (CData.connections[_msgPack.index].Status == 0)
                    {
                        if (CData.playerData.ContainsKey(username))
                        {
                            Boolean isLoggedIn = false;
                            foreach (CPlayer p in CData.connections.Values)
                            {
                                if (p.Status == 1 && p.Username.Equals(username))
                                {
                                    isLoggedIn = true;
                                }
                            }

                            if (!isLoggedIn)
                            {

                                if (CMD5Hash.VerifyMD5Hash(password, CData.playerData[username]))
                                {
                                    CData.connections[_msgPack.index].Password = password;
                                    CData.connections[_msgPack.index].Status = 1;
                                    CMessageSS okMsg = new CMessageSS(10, 0, 0, "");
                                    CMessagePack<CMessageSS> okMsgPack = new CMessagePack<CMessageSS>(okMsg, _msgPack.index);
                                    server.Send(okMsgPack);

                                    _console.SendOutput("");
                                    _console.SendOutput(_msgPack.index + "号客户端成功登录游戏：" + username);
                                }
                                else
                                {
                                    CMessageSS wrongPassMsg = new CMessageSS(16, 0, 0, password);
                                    CMessagePack<CMessageSS> wrongPassMsgPack = new CMessagePack<CMessageSS>(wrongPassMsg, _msgPack.index);
                                    server.Send(wrongPassMsgPack);

                                    _console.SendOutput("");
                                    _console.SendOutput(_msgPack.index + "号客户端尝试登录游戏，但密码不正确：" + username);
                                }
                            }
                            else
                            {
                                CMessageSS loggedInMsg = new CMessageSS(13, 0, 0, username);
                                CMessagePack<CMessageSS> loggedInMsgPack = new CMessagePack<CMessageSS>(loggedInMsg, _msgPack.index);
                                server.Send(loggedInMsgPack);

                                _console.SendOutput("");
                                _console.SendOutput(_msgPack.index + "号客户端尝试登录游戏，但已经有客户端使用该用户名登录游戏：" + username);
                            }
                        }
                        else
                        {
                            CMessageSS nameNotExistMsg = new CMessageSS(12, 0, 0, username);
                            CMessagePack<CMessageSS> nameNotExistMsgPack = new CMessagePack<CMessageSS>(nameNotExistMsg, _msgPack.index);
                            server.Send(nameNotExistMsgPack);

                            _console.SendOutput("");
                            _console.SendOutput(_msgPack.index + "号客户端尝试登录游戏，但用户尚未被创建：" + username);
                        }
                    }
                    else
                    {
                        CMessageSS clientLoggedInMsg = new CMessageSS(13, 0, 0, username);
                        CMessagePack<CMessageSS> clientLoggedInMsgPack = new CMessagePack<CMessageSS>(clientLoggedInMsg, _msgPack.index);
                        server.Send(clientLoggedInMsgPack);

                        _console.SendOutput("");
                        _console.SendOutput(_msgPack.index + "号客户端尝试登录游戏，但该客户端已经登录游戏：" + username);
                    }
                }
            }
            else if (msg.MsgCode == 13)
            {
                if (CData.connections[_msgPack.index].Status == 1)
                {
                    CData.connections[_msgPack.index].Username = "";
                    CData.connections[_msgPack.index].Password = "";
                    CData.connections[_msgPack.index].Msg = null;
                    CData.connections[_msgPack.index].Status = 0;

                    CMessageSS okMsg = new CMessageSS(10, 0, 0, "");
                    CMessagePack<CMessageSS> okMsgPack = new CMessagePack<CMessageSS>(okMsg, _msgPack.index);
                    server.Send(okMsgPack);

                    _console.SendOutput("");
                    _console.SendOutput(_msgPack.index + "号客户端成功登出");
                }
                else
                {
                    CMessageSS clientNotLoggedInMsg = new CMessageSS(14, 0, 0, CData.connections[_msgPack.index].Username);
                    CMessagePack<CMessageSS> clientNotLoggedInMsgPack = new CMessagePack<CMessageSS>(clientNotLoggedInMsg, _msgPack.index);
                    server.Send(clientNotLoggedInMsgPack);

                    _console.SendOutput("");
                    _console.SendOutput(_msgPack.index + "号客户端尝试登出游戏，但该客户端尚未登录游戏");
                }
            }
            else
            {
                _console.SendOutput("");
                //_console.SendOutput(_msgPack.index.ToString());
                //_console.SendOutput(_msgPack.message.MsgContent);
                _console.SendOutput(msg.ToString());
            }
        }
    }
}
